package com.campus.campusdelivery.service.impl;

import com.campus.campusdelivery.dto.CreateOrderRequest;
import com.campus.campusdelivery.dto.OrderDto;
import com.campus.campusdelivery.dto.StatsDto;
import com.campus.campusdelivery.entity.*;
import com.campus.campusdelivery.constant.OrderStatus;
import com.campus.campusdelivery.repository.*;
import com.campus.campusdelivery.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    
    private final OrderRepository orderRepository;
    private final OrderItemRepository orderItemRepository;
    private final UserRepository userRepository;
    private final MerchantRepository merchantRepository;
    private final MenuItemRepository menuItemRepository;
    
    @Override
    @Transactional
    public OrderDto createOrder(Long userId, CreateOrderRequest request) {
        // 1. 验证用户存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 2. 验证商家存在
        Merchant merchant = merchantRepository.findById(request.getMerchantId())
                .orElseThrow(() -> new RuntimeException("商家不存在"));
        
        // 3. 生成订单号
        String orderNumber = generateOrderNumber();
        
        // 4. 计算订单金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<OrderItem> orderItems = new ArrayList<>();
        
        for (CreateOrderRequest.OrderItemRequest itemRequest : request.getOrderItems()) {
            MenuItem menuItem = menuItemRepository.findById(itemRequest.getMenuItemId())
                    .orElseThrow(() -> new RuntimeException("菜品不存在: " + itemRequest.getMenuItemId()));
            
            if (!menuItem.getAvailable()) {
                throw new RuntimeException("菜品已下架: " + menuItem.getName());
            }
            
            BigDecimal itemTotal = menuItem.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity()));
            totalAmount = totalAmount.add(itemTotal);
            
            OrderItem orderItem = new OrderItem();
            orderItem.setMenuItem(menuItem);
            orderItem.setItemName(menuItem.getName());
            orderItem.setUnitPrice(menuItem.getPrice());
            orderItem.setQuantity(itemRequest.getQuantity());
            orderItem.setTotalPrice(itemTotal);
            orderItem.setRemark(itemRequest.getRemark());
            
            orderItems.add(orderItem);
        }
        
        // 5. 创建订单
        Order order = new Order();
        order.setOrderNumber(orderNumber);
        order.setUser(user);
        order.setMerchant(merchant);
        order.setStatus(OrderStatus.PENDING);
        order.setTotalAmount(totalAmount);
        order.setDeliveryFee(BigDecimal.valueOf(3.00)); // 固定配送费
        order.setFinalAmount(totalAmount.add(order.getDeliveryFee()));
        order.setDeliveryAddress(request.getDeliveryAddress());
        order.setDeliveryPhone(request.getDeliveryPhone());
        order.setDeliveryName(request.getDeliveryName());
        order.setRemark(request.getRemark());
        
        // 6. 保存订单
        Order savedOrder = orderRepository.save(order);
        
        // 7. 保存订单项
        for (OrderItem orderItem : orderItems) {
            orderItem.setOrder(savedOrder);
            orderItemRepository.save(orderItem);
        }
        
        // 8. 转换为DTO返回
        return convertToDto(savedOrder, orderItems);
    }
    
    private String generateOrderNumber() {
        // 生成订单号: 时间戳 + 随机数
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.valueOf((int)(Math.random() * 1000));
        return timestamp + String.format("%03d", Integer.parseInt(random));
    }
    
    private OrderDto convertToDto(Order order, List<OrderItem> orderItems) {
        OrderDto dto = new OrderDto();
        dto.setId(order.getId());
        dto.setOrderNumber(order.getOrderNumber());
        dto.setUserId(order.getUser().getId());
        dto.setUserName(order.getUser().getUsername());
        dto.setMerchantId(order.getMerchant().getId());
        dto.setMerchantName(order.getMerchant().getShopName());
        dto.setStatus(order.getStatus());
        dto.setTotalAmount(order.getFinalAmount());
        dto.setDeliveryAddress(order.getDeliveryAddress());
        dto.setContactPhone(order.getDeliveryPhone());
        dto.setRemark(order.getRemark());
        dto.setOrderTime(order.getCreateTime());
        
        // 转换订单项
        List<OrderDto.OrderItemDto> itemDtos = orderItems.stream()
                .map(this::convertItemToDto)
                .collect(Collectors.toList());
        dto.setOrderItems(itemDtos);
        
        return dto;
    }
    
    private OrderDto.OrderItemDto convertItemToDto(OrderItem orderItem) {
        OrderDto.OrderItemDto dto = new OrderDto.OrderItemDto();
        dto.setId(orderItem.getId());
        dto.setMenuItemId(orderItem.getMenuItem().getId());
        dto.setMenuItemName(orderItem.getItemName());
        dto.setPrice(orderItem.getUnitPrice());
        dto.setQuantity(orderItem.getQuantity());
        dto.setSubtotal(orderItem.getTotalPrice());
        return dto;
    }
    
    @Override
    public OrderDto getOrderById(Long id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
        return convertToDto(order, orderItems);
    }
    
    @Override
    public Page<OrderDto> getOrdersByUserId(Long userId, Pageable pageable) {
        Page<Order> orderPage = orderRepository.findByUserIdWithPagination(userId, pageable);
        
        List<OrderDto> orderDtos = orderPage.getContent().stream()
                .map(order -> {
                    List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
                    return convertToDto(order, orderItems);
                })
                .collect(Collectors.toList());
        
        return new PageImpl<>(orderDtos, pageable, orderPage.getTotalElements());
    }
    
    @Override
    public Page<OrderDto> getOrdersByUserId(Long userId, Pageable pageable, String status) {
        // 如果状态为空，返回所有订单
        if (status == null || status.isEmpty()) {
            return getOrdersByUserId(userId, pageable);
        }
        
        try {
            OrderStatus orderStatus = OrderStatus.valueOf(status.toUpperCase());
            Page<Order> orderPage = orderRepository.findByUserIdAndStatusWithPagination(userId, orderStatus, pageable);
            
            List<OrderDto> orderDtos = orderPage.getContent().stream()
                    .map(order -> {
                        List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
                        return convertToDto(order, orderItems);
                    })
                    .collect(Collectors.toList());
            
            return new PageImpl<>(orderDtos, pageable, orderPage.getTotalElements());
        } catch (IllegalArgumentException e) {
            // 状态不合法，返回空结果
            return Page.empty(pageable);
        }
    }
    
    @Override
    public Page<OrderDto> getOrdersByMerchantId(Long merchantId, Pageable pageable) {
        // TODO: 实现从数据库获取商家订单
        return Page.empty(pageable);
    }
    
    @Override
    public Page<OrderDto> getOrdersByDeliveryPersonId(Long deliveryPersonId, Pageable pageable) {
        // TODO: 实现从数据库获取配送员订单
        return Page.empty(pageable);
    }
    
    @Override
    public Page<OrderDto> getPendingOrders(Pageable pageable) {
        // TODO: 实现从数据库获取待处理订单
        return Page.empty(pageable);
    }
    
    @Override
    @Transactional
    public void updateOrderStatus(Long id, String status) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        try {
            OrderStatus newStatus = OrderStatus.valueOf(status.toUpperCase());
            order.setStatus(newStatus);
            
            // 根据状态更新相应的时间字段
            LocalDateTime now = LocalDateTime.now();
            switch (newStatus) {
                case PAID:
                    order.setPayTime(now);
                    break;
                case CONFIRMED:
                    order.setConfirmTime(now);
                    break;
                case PREPARING:
                    order.setPreparingTime(now);
                    break;
                case READY:
                    order.setReadyTime(now);
                    break;
                case DELIVERING:
                    order.setDeliveryTime(now);
                    break;
                case COMPLETED:
                    order.setCompletedTime(now);
                    break;
                case CANCELLED:
                    order.setCancelledTime(now);
                    break;
                default:
                    break;
            }
            
            orderRepository.save(order);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("无效的订单状态: " + status);
        }
    }
    
    @Override
    @Transactional
    public void cancelOrder(Long id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 只有待支付和已支付状态的订单可以取消
        if (order.getStatus() != OrderStatus.PENDING && order.getStatus() != OrderStatus.PAID) {
            throw new RuntimeException("当前订单状态不允许取消");
        }
        
        order.setStatus(OrderStatus.CANCELLED);
        order.setCancelledTime(LocalDateTime.now());
        order.setCancelReason("用户取消");
        
        orderRepository.save(order);
    }
    
    @Override
    @Transactional
    public void payOrder(Long id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 只有待支付状态的订单可以支付
        if (order.getStatus() != OrderStatus.PENDING) {
            throw new RuntimeException("订单不在待支付状态");
        }
        
        order.setStatus(OrderStatus.PAID);
        order.setPayTime(LocalDateTime.now());
        
        orderRepository.save(order);
    }
    
    @Override
    public void acceptOrder(Long id) {
        // TODO: 实现接单
    }
    
    @Override
    public void startDelivery(Long id) {
        // TODO: 实现开始配送
    }
    
    @Override
    public void completeDelivery(Long id) {
        // TODO: 实现完成配送
    }
    
    @Override
    public StatsDto getTodayStats() {
        // TODO: 实现今日统计
        return new StatsDto();
    }
    
    @Override
    public List<OrderDto> getRecentOrders(int limit) {
        // TODO: 实现获取最近订单
        return new ArrayList<>();
    }
}
